# !/usr/bin/python3
# --coding:utf-8--
# @Author:吴磊
# @Time: 2019年11月29日17时
# @File: 轻视频下载.py
import requests
import random
import time
import re
from threading import Thread
from queue import Queue


class QingSpider(object):
    # 下载视频
    def download(self, url):
        content = requests.get(url, headers=self.headers).content
        with open(self.filepath + str(random.randint(0, 999999)) + '.mp4', 'wb') as f:
            f.write(content)
        self.count += 1
        print('已下载完成' + str(self.count) + '个')

    # 从文件中获取收藏链接并解析视频地址
    def collectionlist(self):
        print('正在解析数据...')
        with open('./轻视频收藏连接', 'r') as f:
            content = f.read()
        rule1 = re.compile("cursor_next=(.*?)&device")
        rule2 = re.compile("ts=(.*?)&version=2.2.1")
        rule3 = re.compile("sign=(.*?)\n")
        cursor_nexts = re.findall(rule1, content)
        tss = re.findall(rule2, content)
        signs = re.findall(rule3, content)
        headers = {
            'Display-ID': '41060291|27', 'Buvid': 'XY8C127818CBACD4CC8D614BA1C1D51FDEEF6',
            'User-Agent': 'Mozilla/5.0 BBQDroid/2.2.1', 'Device-ID': 'b301310c925a1770',
            'Sessionid': 'f8ebcf7c178c15dd539430ff1aed4a0c',
            'Host': 'bbq.bilibili.com',
            'Connection': 'Keep-Alive',
            'Accept-Encoding': 'gzip'
        }
        for i in range(0, len(cursor_nexts)):
            url = 'https://bbq.bilibili.com/qing/user/favorite/list?access_key=9695f6b2a9098bb988626f4dc42197b1&' \
                  'appkey=cc578d267072c94d&build=221000&channel=official' \
                  f'&cursor_next={cursor_nexts[i]}&device=OPPO&mobi_' \
                  f'app=android_bbq&obj_type=1&platform=android&ts={tss[i]}&version=2.2.1&sign={signs[i]}'
            result = requests.get(url, headers=headers).json()['data']['list']
            for j in result:
                self.finalurl.append(j['play']['file_info'][0]['url'])
        # 链接去重
        self.finalurl = list(set(self.finalurl))
        k = 0
        for i in self.finalurl:
            # 过滤掉失效的链接
            if 'http' in i:
                self.url_queue.put(i)
            k += 1
        print("视频总计: "+str(k)+'个')

    def __init__(self):
        self.headers = {
            'User-Agent': 'Bilibili BBQ/Android',
            'Accept': '*/*',
            'Range': 'bytes=0-',
            'Connection': 'close'
        }
        self.filepath = 'E:\\代码生成文件\\轻视频\\'
        self.finalurl = []
        # url队列
        self.url_queue = Queue()
        self.count = 0

    # 线程事件函数
    def get_data(self):
        while True:
            if self.url_queue.empty():
                break
            # get地址,请求+解析+保存
            url = self.url_queue.get()
            self.download(url)

    def option(self):
        option = input('\n是否具备上述必要条件(y/n): ')
        if option == 'y':
            # url入队列
            self.collectionlist()
            print("正在准备开始下载...")
            # 创建多线程
            t_list = []
            # 开启六个线程
            for i in range(6):
                t = Thread(target=self.get_data)
                t_list.append(t)
                t.start()
            for i in t_list:
                i.join()
        elif option == 'n':
            print('只有存在上述条件才能运行,赶快去准备吧')
            self.option()
        elif option == 'exit':
            exit()
        else:
            print('请输入正确操作')
            self.option()

    # 主函数
    def main(self):
        tips = """使用方法:
1. 在进入轻视频我的收藏页面,使用手机httpcanary抓包
2. 在抓包软件中过滤favorite关键词
3. 将链接写入到"轻视频收藏链接"中
4. 将上面的文件移动到本软件所在目录中
5. 退出软件输入exit
"""
        print(tips)
        self.option()


if __name__ == '__main__':
    start = time.time()
    spider = QingSpider()
    spider.main()
    end = time.time()
    print('执行时间:%.2f秒' % (end - start))
